/********************************************************************
*   Compare the time and the alarm that be set.                     *
*   Control the way that buzzer beeps                               *
********************************************************************/

module buzzerCtrl #(
  parameter SYS_CLK = 50_000_000
)(
  input   wire        clk    ,
  input   wire        rstn   ,
  input   wire        ena    ,

  input   wire [7:0]  t_hour ,
  input   wire [7:0]  t_min  ,
  input   wire [7:0]  t_sec  ,

  input   wire [7:0]  a_hour ,
  input   wire [7:0]  a_min  ,
  input   wire [7:0]  a_sec  ,

  output  reg         beep_en
);

localparam  DELAY = SYS_CLK / 2;
localparam  IDLE  = 1'b0,
            BEEP  = 1'b1;

reg         state    ;
reg  [25:0] cnt_500ms;
reg  [ 3:0] cnt      ;

always @(posedge clk or negedge rstn) begin
  if(~rstn)
    state   <=  IDLE;
  else begin
    case(state)
      IDLE: 
        if(t_hour == a_hour && t_min == a_min && t_sec == a_sec/* && t_AM_PM == a_AM_PM*/)
          state   <=  BEEP;
      BEEP:
        if(cnt == 4'd15 && cnt_500ms == DELAY - 1)
          state   <=  IDLE;
    endcase
  end
end

always @(*) begin
  if(~ena)
      beep_en = 1'b0;
  else
    case(state)
    	IDLE: beep_en = 1'b0;
    	BEEP: 
				begin
    	  	case (cnt)
    	  	  4'd0, 4'd2, 4'd4, 4'd6,
    	  	  4'd8, 4'd10, 4'd12, 4'd14: beep_en = 1'b1;
    	  	  4'd1, 4'd3, 4'd5, 4'd7,
    	  	  4'd9, 4'd11, 4'd13, 4'd15: beep_en = 1'b0;
    	  	endcase
    		end
    endcase
end

always @(posedge clk or negedge rstn) begin
  if(~rstn)
    cnt_500ms   <=  26'd0;
  else if (state == BEEP) begin
    if (cnt_500ms == DELAY - 1)
      cnt_500ms   <=  26'd0;
    else
      cnt_500ms   <=  cnt_500ms + 1'b1;
  end else
    cnt_500ms   <=  26'd0;
end

always @(posedge clk or negedge rstn) begin
  if(~rstn)
    cnt   <=  4'd0;
  else if (state == BEEP && cnt_500ms == DELAY - 1)
    cnt   <=  cnt + 1'b1;
  else
    cnt   <=  4'd0;
end

endmodule
